package com.knight;


import com.knight.model.EntityDataModel;
import com.knight.util.CamelCaseUtil;
import com.knight.util.MysqlDataType2JavaDataType;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.*;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Hello world!
 */

/**
 * @author suxin
 */
public class GeneratorMain {

    /**
     * 数据库连接
     */
    private Connection connection;

    /**
     * 数据库元数据对象
     */
    private DatabaseMetaData databaseMetaData;

    /**
     * 读取配置
     */
    private Properties config = new Properties();

    public GeneratorMain() {
        //读取配置文件
        readConfiguration();
        //数据库初始化
        initDateBase();
    }

    /**
     * 读取配置
     */
    public void readConfiguration() {
        try {
            InputStream in = this.getClass().getResourceAsStream("/config.properties");
            config.load(in);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 数据库初始化
     */
    public void initDateBase() {
        try {
            Properties props = new Properties();
            props.setProperty("user", config.getProperty("db_username"));
            props.setProperty("password", config.getProperty("db_password"));
            props.setProperty("remarks", "true");
            //设置可以获取tables remarks信息
            props.setProperty("useInformationSchema", "true");
            Class.forName("com.mysql.jdbc.Driver");
            connection = DriverManager.getConnection(config.getProperty("db_url"), props);
            databaseMetaData = connection.getMetaData();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public Connection getConnection() {
        return connection;
    }

    public void setConnection(Connection connection) {
        this.connection = connection;
    }

    public DatabaseMetaData getDatabaseMetaData() {
        return databaseMetaData;
    }

    public void setDatabaseMetaData(DatabaseMetaData databaseMetaData) {
        this.databaseMetaData = databaseMetaData;
    }

    public Properties getConfig() {
        return config;
    }

    public void setConfig(Properties config) {
        this.config = config;
    }


    /**
     * 实体生成
     */
    public void generatingEntity() throws SQLException, IOException, TemplateException {
        Map<String, EntityDataModel> dataMap = new HashMap<>(16);
        ResultSet resultSet = databaseMetaData.getTables(config.getProperty("db_catalog"), config.getProperty("db_username"), "%", new String[]{"TABLE"});
        while (resultSet.next()) {
            //表名
            String tableName = CamelCaseUtil.toCapitalizeCamelCase(resultSet.getString("TABLE_NAME"));
            //表备注
            String tableNote = resultSet.getString("REMARKS");
            //组装参数
            EntityDataModel entityDataModel = new EntityDataModel();
            entityDataModel.setPackagePath(config.getProperty("packagePath"));
            entityDataModel.setEntityName(tableName);
            entityDataModel.setEntityNote(tableNote);
            entityDataModel.setEntityNamePrefix(config.getProperty("entityNamePrefix"));
            entityDataModel.setEntityNameSuffix(config.getProperty("entityNameSuffix"));
            entityDataModel.setAttributesList(new ArrayList<>());
            entityDataModel.setImportPackageList(new ArrayList<>());

            ResultSet resultSet2 = databaseMetaData.getColumns(null, null, resultSet.getString("TABLE_NAME"), null);
            while (resultSet2.next()) {
                //列名
                String columnName = CamelCaseUtil.toCamelCase(resultSet2.getString("COLUMN_NAME"));
                String columnComment = resultSet2.getString("REMARKS");//对应的java.sql.Types的SQL类型(列类型ID)
                int dataType = resultSet2.getInt("DATA_TYPE");
                JDBCType jdbcType = JDBCType.valueOf(dataType);
                EntityDataModel.Attributes attributes = new EntityDataModel.Attributes();
                attributes.setFieldName(columnName);
                attributes.setFieldNote(columnComment);
                attributes.setJdbcType(jdbcType);
                entityDataModel.getAttributesList().add(attributes);
            }
            MysqlDataType2JavaDataType.toJavaDataType(entityDataModel);
            dataMap.put(tableName, entityDataModel);
        }

        Configuration configuration = new Configuration(Configuration.VERSION_2_3_30);
        configuration.setTemplateLoader(new ClassTemplateLoader(GeneratorMain.class, "/template/"));
        Template template = configuration.getTemplate("entity.ftl", "UTF-8");
        for (EntityDataModel entityDataModel : dataMap.values()) {
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(config.getProperty("outputLocation") + entityDataModel.getEntityNamePrefix() + entityDataModel.getEntityName() + entityDataModel.getEntityNameSuffix() + ".java"), "UTF-8"));
            template.process(entityDataModel, out);
        }
    }

    /**
     * Mapper接口生成
     */
    public void generatingMapper() throws Exception{

    }
}
